package com.lht.testDemo;

import java.util.Random;
import java.util.concurrent.*;

/**
 * @author Eric
 * @version 1.0
 * @date 2019-06-20
 */
public class ForkJoinTaskDemo {
    private class SumTask extends RecursiveTask<Long> {

        private static final int THRESHOLD = 25000000;

        private int arr[];
        private int start;
        private int end;

        public SumTask(int[] arr, int start, int end) {
            this.arr = arr;
            this.start = start;
            this.end = end;
        }

        /**
         * 小计
         */
        private Long subtotal() {
            Long sum = 0L;
            for (int i = start; i < end; i++) {
                sum += arr[i];
            }
//            System.out.println(Thread.currentThread().getName() + ": ∑(" + start + "~" + end + ")=" + sum);
            return sum;
        }

        @Override
        protected Long compute() {

            if ((end - start) <= THRESHOLD) {
                return subtotal();
            }else {
                int middle = (start + end) / 2;
                SumTask left = new SumTask(arr, start, middle);
                SumTask right = new SumTask(arr, middle, end);
                left.fork();
                right.fork();

                return left.join() + right.join();
            }
        }
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {

        int size=10000*10000;
        int[] arr = new int[size];
        Random random=new Random();
        for(int i=0;i<size;i++){
            arr[i]=random.nextInt(5);
        }

        Long start=System.nanoTime();
        Long sum=0L;
        for(int i=0;i<size;i++){
            sum+=arr[i];
        }
        Long end=System.nanoTime();
        Long count=end-start;
        System.out.println("单线程耗时："+count+",计算结果："+sum);

        start=System.nanoTime();
        ForkJoinPool pool = new ForkJoinPool();
        ForkJoinTask<Long> result = pool.submit(new ForkJoinTaskDemo().new SumTask(arr, 0, arr.length));
        end=System.nanoTime();
        count=end-start;
        System.out.println("耗时："+count+",最终计算结果: " + result.invoke());
        pool.shutdown();
    }
}
